using System;
using System.Collections.Generic;
using System.Linq;
using CustomORM.DataAccess;
using CustomORM.Examples.Entities;
using CustomORM.Repository;

namespace CustomORM.Examples
{
    public class CustomerRepository : RepositoryBase
    {
        public CustomerRepository(IDataAccess dataAccess)
            : base(dataAccess)
        {
        }

        /// <summary>
        /// This method fetches Customer with surrounding Orders
        /// By adding SQL text will parameters embeded
        /// (yeah, everyone knows about SQL injectsions, but if you are working with some crap db that doesn't support those)
        /// </summary>
        /// <param name="customerId"></param>
        /// <returns></returns>
        public Customer FetchCustomerByID_FormatSql(string customerId)
        {
            Criteria criteria = CreateCriteria(typeof(Customer), "c")
                .AddEntity(typeof(Order), "o")
                .AddSQL(
                        @"join Orders o
                        on c.[Customer ID] = o.[Customer ID]
                        where c.[Customer ID] = '{0}'", customerId);

            List<Customer> customers = ExecuteCriteria<Customer>(criteria);

            return customers.First();
        }

        public Customer FetchCustomerByID(string customerId)
        {
            Criteria criteria = CreateCriteria(typeof(Customer), "c")
                .AddEntity(typeof(Order), "o")
                .AddEntity(typeof(Employee), "e")
                .AddSQL(
                        @"left join Orders o
                        on c.[Customer ID] = o.[Customer ID]
                        left join Employees e
                        on e.[Employee ID] = o.[Employee ID]
                        where c.[Customer ID] = @customerId")
                .AddParameter("@customerId", customerId);

            List<Customer> customers = ExecuteCriteria<Customer>(criteria);

            return customers.FirstOrDefault();
        }

        public List<Customer> FetchAllCustomers()
        {
            Criteria criteria = CreateCriteria(typeof(Customer), "c")
            .AddEntity(typeof(Order), "o")
            .AddEntity(typeof(Employee), "e")
            .AddSQL(
                @"left join Orders o
                on c.[Customer ID] = o.[Customer ID]
                left join Employees e
                on e.[Employee ID] = o.[Employee ID]");

            List<Customer> customers = ExecuteCriteria<Customer>(criteria);

            return customers;
        }

        public Customer SaveCustomer(Customer customer)
        {
            var transaction = BeginTransaction();

            Customer savedCustomer = null;
            try
            {
                savedCustomer = Save(customer);
                transaction.Commit();
            }
            catch (Exception)
            {
                transaction.Rollback();
            }
            
            return savedCustomer;
        }

        public void DeleteCustomer(Customer customer)
        {
            var transaction = BeginTransaction();

            try
            {
                Delete(customer);
                transaction.Commit();
            }
            catch (Exception)
            {
                transaction.Rollback();
            }
        }
    }

}